package com.infore.dataAudit.service.impl;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.annotation.Resource;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.infore.dataAudit.conf.ProcessDeployAutoSettings;
import com.infore.dataAudit.dto.HourData;
import com.infore.dataAudit.dto.Project;
import com.infore.dataAudit.dto.SpanDrift;
import com.infore.dataAudit.dto.ZeroDrift;
import com.infore.dataAudit.enums.AirAuditUsers;
import com.infore.dataAudit.enums.ResultStatus;
import com.infore.dataAudit.remote.IBaseDataService;
import com.infore.dataAudit.remote.IQualityControlService;
import com.infore.dataAudit.remote.IReceiveDataService;
import com.infore.dataAudit.remote.IStatisticsAndAlarm;
import com.infore.dataAudit.service.DeployService;
import com.infore.dataAudit.service.RunningTimeService;
import com.infore.dataAudit.util.Constants;
import com.infore.dataAudit.util.ObjectMapperUtil;
import com.infore.dataAudit.util.ResultEntity;
import com.infore.dataAudit.vo.QualityParamOutSelectBo;





/**
 * deploy服务层
 * @author cys
 *
 */
@Service("deployService")
public class DeployServiceImpl implements DeployService {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private ObjectMapper objectMapper;
    
    @Resource
    private RunningTimeService runningTimeService;
    @Autowired
    private IReceiveDataService receiveDataService;
    @Autowired
    private IQualityControlService qualityControlService;
    @Autowired
    private IBaseDataService baseDataService;
    @Autowired
    private ObjectMapperUtil objectMapperUtil;
    
    @Autowired
    private ProcessDeployAutoSettings processDeployAutoSettings;
    @Autowired
    IStatisticsAndAlarm statisticsAndAlarm;

    @Override
    public ResultEntity addDeploy(MultipartFile deployFile) throws IOException {
        if (deployFile == null) {
            return null;
        }
        Deployment deploy = repositoryService.createDeployment() // 创建部署
                .name(deployFile.getOriginalFilename()) // 需要部署流程名称
                .addZipInputStream(new ZipInputStream(deployFile.getInputStream()))// 添加ZIP输入流
                .deploy(); // 开始部署
        if (deploy != null) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult(); 
            BpmnModel model = repositoryService.getBpmnModel(processDefinition.getId());
            BpmnJsonConverter converter = new BpmnJsonConverter();
            ObjectNode modelNode = converter.convertToJson(model);
            Model modelData = repositoryService.newModel();
            ObjectNode modelObjectNode = objectMapper.createObjectNode();
            
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, processDefinition.getVersion());
            modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
            modelData.setMetaInfo(modelObjectNode.toString());
            modelData.setName(processDefinition.getName());
            modelData.setKey(processDefinition.getKey());
            modelData.setVersion(processDefinition.getVersion());
            modelData.setTenantId(processDefinition.getTenantId());
            
            repositoryService.saveModel(modelData);
            repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));
            
            return new ResultEntity(ResultStatus.SUCCESS, "部署成功");
        }
        return new ResultEntity(ResultStatus.ERROR, "部署流程失败");
    }

    @Override
    public ResultEntity delDeploy(String fileNames) {
        if (fileNames == null || fileNames.trim().isEmpty()) {
            return new ResultEntity(ResultStatus.ERROR, "参数错误!");
        }
        String[] names = fileNames.split(",");

        for (String name : names) {
            repositoryService.deleteDeployment(name.trim(), true);
        }
        return new ResultEntity(ResultStatus.SUCCESS, "删除成功");
    }

    @Override
    public Map<String, Object> queryDeployByPage(String deployName, Integer pageSize, Integer page) {
        long count = repositoryService.createDeploymentQuery().deploymentNameLike("%" + deployName + "%").count();
        Map<String, Object> resultmap = new HashMap<String, Object>();
        if (count != 0L) {
            List<Deployment> deployList = repositoryService.createDeploymentQuery()// 创建流程查询实例
                    .orderByDeploymenTime().desc() // 降序
                    .deploymentNameLike("%" + deployName + "%") // 根据Name模糊查询
                    .listPage(page, pageSize);
            resultmap.put("rows", deployList);
        } else {
            resultmap.put("rows", null);
        }
        resultmap.put("total", count);
        return resultmap;
    }
    
    @Override
    public void startAuditFlow(String zdTime) {
        //1 获取前一天的0点开始23点 站点数据 过滤只要监测站数据 监测站mn
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String quTimeEnd = sdf.format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        String time = sdf.format(calendar.getTime());
        //当天下午四点自动完成 为人工完成的话
        String oneTimeEnd = this.getOneTimeEnd();
        //oneTimeEnd = "2019-04-24T12:00:11";
        //下个月7号
        System.out.println("任务调度开始-------------");
        System.out.println("自定时间补传审核-------------" + zdTime);
        //time = "2019-06-09";
        if(zdTime != null) {
            time = zdTime;
        }
        String oneTimeEnd2 = this.getOneTimeEnd2();
       // oneTimeEnd2 = "2019-05-23T14:50:11";
        List<String> mnList = new ArrayList<>();
        //查询站点监测小时数据
        ResultEntity re = receiveDataService.queryHourData(time + " 00:00:00", time + " 23:59:59");
        List<HourData> HourDatas = objectMapperUtil.convertList(re, HourData.class);
        Map<String, List<HourData>> mapHourData = new HashMap<>();
        for (HourData hourData : HourDatas) {
            String mn = hourData.getMn();
            if(mapHourData.get(mn) == null) {
                mnList.add(mn);
                mapHourData.put(mn, new ArrayList<>());
            }
            mapHourData.get(mn).add(hourData);
        }
        Constants.setStationHourData(mapHourData);
        //查询日零点
        QualityParamOutSelectBo qualityParamSelectBo = new QualityParamOutSelectBo();
        List<String> indexCodes = this.getIndexCodes();
        qualityParamSelectBo.setStartTime(time + " 00:00:00");
        qualityParamSelectBo.setEndTime(quTimeEnd + " 23:00:00");
        qualityParamSelectBo.setStationCodes(mnList);
        qualityParamSelectBo.setIndexCodes(indexCodes);
        ResultEntity zeroRe =  qualityControlService.zeroDriftData(qualityParamSelectBo);
        ResultEntity spanRe =  qualityControlService.spanDriftData(qualityParamSelectBo);
        //零点数据 存储值静态变量中
        this.setZeroDriftData(zeroRe);
        //跨度数据 存储值静态变量中
        this.setSpanDriftData(spanRe);
        //System.out.println(Constants.getStationSpanDrift());
       // System.out.println(Constants.getStationZeroDrift());
        //String[] stationMns = {};
        Map<String, Object> params = null;
        for (String mn : mnList) {
            params = new HashMap<>(); 
//            params.put("userId1", "熊律欣");
//            params.put("userId2", "武云霞");
//            params.put("userId3", "卢凤媛");
            params.put("userId1", AirAuditUsers.YW.getStatusCode());
            params.put("userId2", AirAuditUsers.XZ.getStatusCode());
            params.put("userId3", AirAuditUsers.SQ.getStatusCode());
            params.put("stationMn", mn);
            params.put("stationTime", time);
            params.put("oneTimeEnd", oneTimeEnd);
            params.put("oneTimeEnd2", oneTimeEnd2);
            runningTimeService.startProcess(processDeployAutoSettings.getDataAuditKey(), params);
        }
      //  ResultEntity result = runningTimeService.startProcess("audioFlow01", null);
      //  log.info("数据审核开启--The time is now {}",result.getContent() +"--"+ dateFormat.format(new Date()));
    }
    
    @Override
    public void startAirAuditFlow(String zdTime) {
        //1 获取前一天的0点开始23点 站点数据 过滤只要监测站数据 监测站mn
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String quTimeEnd = sdf.format(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        String time = sdf.format(calendar.getTime());
        //当天下午四点自动完成 为人工完成的话
        String oneTimeEnd = this.getOneTimeEnd();
        //oneTimeEnd = "2019-04-24T12:00:11";
        //下个月7号
        System.out.println("任务调度开始 空气站审核-------------");
        System.out.println("自定时间补传审核-------------" + zdTime);
        //time = "2019-06-09";
        if(zdTime != null) {
            time = zdTime;
        }
        String oneTimeEnd2 = this.getOneTimeEnd2();
       // oneTimeEnd2 = "2019-05-23T14:50:11";
        List<String> mnList = new ArrayList<>();
        //查询站点监测小时数据
        ResultEntity re = statisticsAndAlarm.queryHourDataAirByTime(time + " 00:00:00", time + " 23:59:59");
        List<HourData> HourDatas = objectMapperUtil.convertList(re, HourData.class);
        Map<String, List<HourData>> mapHourData = new HashMap<>();
        for (HourData hourData : HourDatas) {
            String mn = hourData.getMn();
            if(mapHourData.get(mn) == null) {
                mnList.add(mn);
                mapHourData.put(mn, new ArrayList<>());
            }
            mapHourData.get(mn).add(hourData);
        }
        //用于自动审核
        Constants.setStationHourData(mapHourData);
        //查询日零点
        QualityParamOutSelectBo qualityParamSelectBo = new QualityParamOutSelectBo();
        List<String> indexCodes = this.getIndexCodes();
        qualityParamSelectBo.setStartTime(time + " 00:00:00");
        qualityParamSelectBo.setEndTime(quTimeEnd + " 23:00:00");
        qualityParamSelectBo.setStationCodes(mnList);
        qualityParamSelectBo.setIndexCodes(indexCodes);
        ResultEntity zeroRe =  qualityControlService.zeroDriftData(qualityParamSelectBo);
        ResultEntity spanRe =  qualityControlService.spanDriftData(qualityParamSelectBo);
        //零点数据 存储值静态变量中
        this.setZeroDriftData(zeroRe);
        //跨度数据 存储值静态变量中
        this.setSpanDriftData(spanRe);
        //System.out.println(Constants.getStationSpanDrift());
       // System.out.println(Constants.getStationZeroDrift());
        //String[] stationMns = {};
        Map<String, Object> params = null;
        //空气站通州默认写死 先
        for (String mn : mnList) {
            params = new HashMap<>(); 
            params.put("userId1", AirAuditUsers.YW.getStatusCode());
            params.put("userId2", AirAuditUsers.XZ.getStatusCode());
            params.put("userId3", AirAuditUsers.SQ.getStatusCode());
            params.put("stationMn", mn);
            params.put("stationTime", time);
            params.put("oneTimeEnd", oneTimeEnd);
            params.put("oneTimeEnd2", oneTimeEnd2);
            runningTimeService.startProcess(processDeployAutoSettings.getDataAuditKey(), params);
        }
      //  ResultEntity result = runningTimeService.startProcess("audioFlow01", null);
      //  log.info("数据审核开启--The time is now {}",result.getContent() +"--"+ dateFormat.format(new Date()));
    }
    
    private List<String> getIndexCodes() {
        List<String> indexCodes = new ArrayList<>();
        ResultEntity re = baseDataService.projectInfoAllAudit();
        List<Project> ProjectList = objectMapperUtil.convertList(re, Project.class);
        for (Project project : ProjectList) {
            indexCodes.add(project.getProjectCode());
        }
        return indexCodes;
    }

    private void setSpanDriftData(ResultEntity spanRe) {
        List<SpanDrift> zeroDriftDatas = objectMapperUtil.convertList(spanRe, SpanDrift.class);
        Map<String, List<SpanDrift>> map = new HashMap<>();
        Constants.setStationSpanDrift(map);
        String mn = null;
        for (SpanDrift spanDrift : zeroDriftDatas) {
            mn = spanDrift.getStationCode();
            if(map.get(mn) == null) {
                map.put(mn, new ArrayList<>());
            }
            map.get(mn).add(spanDrift);
        }
    }

    private void setZeroDriftData(ResultEntity zeroRe) {
        List<ZeroDrift> zeroDriftDatas = objectMapperUtil.convertList(zeroRe, ZeroDrift.class);
        Map<String, List<ZeroDrift>> map = new HashMap<>();
        Constants.setStationZeroDrift(map);
        String mn = null;
        for (ZeroDrift zeroDrift : zeroDriftDatas) {
            mn = zeroDrift.getStationCode();
            if(map.get(mn) == null) {
                map.put(mn, new ArrayList<>());
            }
            map.get(mn).add(zeroDrift);
        }
    }

    /**
     * 获取一级人工审核时间限制点
     *  超时完成任务 16点
     * @author 蔡永顺
     * @return String
     * @return
     * @date 2019年4月24日下午6:52:57
     */
    private String getOneTimeEnd() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String time = sdf.format(new Date()) +"T16:00:00";
        return time;
    }
    
    
    /**
     * 获取二级人工审核 省级审核
     * 下个月7号
     * @author 蔡永顺
     * @return String
     * @return
     * @date 2019年4月24日下午6:54:19
     */
    private String getOneTimeEnd2() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String time = sdf.format(calendar.getTime()) +"-07T00:00:00";
        return time;
    }

}
